﻿using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Magiq.Delete;
using Magiq.Insert;
using Magiq.Support;
using Magiq.Update;

namespace Magiq.Objects {
    public class MagiqToObjects : IMagiqProvider, IUpdateProvider, IDeleteProvider, IInsertProvider {
        private readonly EnumerableSourceFinder enumerableSourceFinder = new EnumerableSourceFinder();
        #region IDeleteProvider Members

        public int Execute<T>(IQueryableDelete<T> delete) where T : class {
            return new EnumerableDelete<T>(delete.Where).Execute();
        }

        #endregion

        #region IInsertProvider Members

        public int Execute<TFrom, TDestination, TNew>(IQueryableInsert<TFrom, TDestination, TNew> insert) where TDestination : class {
            return new EnumerableInsert<TFrom, TNew>(insert.Source, insert.NewExpression).Into(insert.Destination);
        }

        #endregion

        #region IMagiqProvider Members

        public IUpdateProvider GetUpdateProvider() {
            return this;
        }

        public IDeleteProvider GetDeleteProvider() {
            return this;
        }

        public IInsertProvider GetInsertProvider() {
            return this;
        }

        public IQueryable<T> CreateQueryableFrom<T>(IEnumerable<T> enumerable) where T : class {
            return enumerable.AsQueryable();
        }

        public bool Handles(IEnumerable source) {
            return true;
        }

        public bool Handles(IEnumerable source, IEnumerable destination) {
            return true;
        }

        public IItemsAdder<TNew> ItemAdderFor<TNew, TDestination>(IEnumerable<TDestination> enumerable) where TDestination : class {
            return new ListItemsAdder<TNew>(enumerableSourceFinder.FindSourceOf(enumerable));
        }

        #endregion

        #region IUpdateProvider Members

        public int Execute<T>(IQueryableUpdate<T> update) where T : class {
            return new EnumerableUpdate<T>(update.Where, update.PropertySets).Update();
        }

        #endregion
    }
}
